package com.apimarket.service;

import com.alibaba.druid.util.StringUtils;
import com.apimarket.annotation.MultiDSTransactionalAnnotation;
import com.apimarket.dao.ApplyMapper;
import com.apimarket.dao.RoutePathsMapper;
import com.apimarket.entity.kong.AclCredential;
import com.apimarket.entity.kong.Consumer;
import com.apimarket.entity.kong.KeyAuthCredential;
import com.apimarket.entity.kong.Plugin;
import com.apimarket.enums.ExceptionEnum;
import com.apimarket.exception.AMException;
import com.apimarket.factory.JsonMapperFactory;
import com.apimarket.slaveDao.ConsumerDao;
import com.apimarket.util.UrlUtil;
import com.apimarket.util.kong.KongConsumer;
import com.apimarket.util.kong.impl.ConsumerBindAcl;
import com.apimarket.util.kong.impl.ConsumerBindKeyAuth;
import com.apimarket.util.kong.impl.KongConsumerOperation;
import com.apimarket.util.net.DeleteNetContext;
import com.apimarket.util.net.GetNetContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.net.URISyntaxException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.*;

@Service
public class ConsumerService {
    @Autowired
    private ConsumerDao consumerDao;
    @Autowired
    private RoutePathsMapper routePathsMapper;
    @Autowired
    private ApplyMapper applyMapper;

    private String listPath="/consumers";
    private String delPath="/consumers";

    @Autowired
    @Qualifier("consumerBindKeyAuth")
    //private KongConsumer<KeyAuthCredential> consumerBindKeyAuth;
    private ConsumerBindKeyAuth consumerBindKeyAuth;

    @Autowired
    @Qualifier("consumerBindAcl")
    //private KongConsumer<AclCredential> consumerBindAcl;
    private ConsumerBindAcl consumerBindAcl;

    @Autowired
    private KongConsumerOperation kongConsumerOperation;

    public KeyAuthCredential generateKeyForConsumer(String nameOrId) throws IOException, URISyntaxException {
        return consumerBindKeyAuth.bindPlugin(nameOrId);
    }

    public AclCredential assignGroupForConsumer(String nameOrId, String group) throws IOException, URISyntaxException {
        return consumerBindAcl.bindPlugin(nameOrId, group);
    }

    public List<KeyAuthCredential> getKeyAuthCredentialViaConsumer(String nameOrId) throws IOException, URISyntaxException {
        return consumerBindKeyAuth.listBindPluginDetailViaConsumer(nameOrId);
    }

    public List<AclCredential> getAclCredentialViaConsumer(String nameOrId) throws IOException, URISyntaxException {
        return consumerBindAcl.listBindPluginDetailViaConsumer(nameOrId);
    }

    public List<Consumer> getConsumer() throws IOException, URISyntaxException {
        UrlUtil urlUtil = new UrlUtil(new GetNetContext(consumerBindKeyAuth.getBaseUrl() + listPath, null));
        JsonNode root = urlUtil.getJsonRoot();
        ObjectMapper mapper = JsonMapperFactory.getInstance();
        CollectionType listType = mapper.getTypeFactory().constructCollectionType(ArrayList.class, com.apimarket.entity.kong.Consumer.class);
        return mapper.readValue(root.get("data").toString(), listType);
    }

    public Consumer getConsumerById(String id) throws IOException, URISyntaxException {
        String targetUrl = consumerBindKeyAuth.getBaseUrl() + listPath + "/" + id;
        UrlUtil urlUtil = new UrlUtil(new GetNetContext(targetUrl, null));
        JsonNode root = urlUtil.getJsonRoot();
        return JsonMapperFactory.getInstance().readValue(root.toString(), com.apimarket.entity.kong.Consumer.class);
    }

    public void delConsumer(String id) throws IOException, URISyntaxException {
        String targetUrl = delPath + "/" + id;
        UrlUtil urlUtil = new UrlUtil(new DeleteNetContext(consumerBindKeyAuth.getBaseUrl() + targetUrl));
        urlUtil.getJsonRoot();
        //删除这个用户对应的申请
        applyMapper.deleteByUserId(id);
    }


    public void delAclGroup(String id) throws IOException, URISyntaxException {
        consumerDao.delAclGroupById(id);
        /*List<String> temp=new ArrayList<>();
        temp.add("/sharonRoute");
        routePathsMapper.addPathList(temp);*/
        //int i=1/0;
    }

    public AclCredential addGroup(String id, String group) throws IOException, URISyntaxException {
        AclCredential acl=consumerBindAcl.addGroup(id,group);
        return acl;
    }

    public List<KeyAuthCredential> getConsumerKeyAuth(String id) throws IOException, URISyntaxException {
        List<KeyAuthCredential> list=consumerBindKeyAuth.listBindPluginDetailViaConsumer(id);
        return list;
    }

    public void delKeyAuth(String consumerId, String keyAuthId) throws IOException, URISyntaxException {
        if(StringUtils.isEmpty(consumerId)||StringUtils.isEmpty(keyAuthId)){
            throw new AMException(ExceptionEnum.ID_IS_NULL);
        }
        consumerBindKeyAuth.delKeyAuth(consumerId,keyAuthId);
    }

    public List<Plugin> getConsumerPlugins(String id) throws IOException, URISyntaxException {
        List<Plugin> list=kongConsumerOperation.getConsumerPlugins(id);
        return list;
    }

    public String getConsumerOneKeyAuth(String userId, String downloadUrl) throws IOException, URISyntaxException {
        List<KeyAuthCredential> list = getConsumerKeyAuth(userId);
        String key=null;
        if(list==null||list.size()==0){
            //如果这个用户没有秘钥，就为这个用户绑定一个秘钥
            KeyAuthCredential keyAuthCredential = generateKeyForConsumer(userId);
            key=keyAuthCredential.getKey();
        }else{
            key=list.get(0).getKey();
        }
        StringBuilder sb=new StringBuilder(downloadUrl);
        sb.append("?apikey=").append(key);
        return sb.toString();
    }

    public String addConsumer(String username) throws IOException, URISyntaxException {
        Map<String,Object> params=new HashMap<>();
        //需要制定用户的id
        String id = UUID.randomUUID().toString();
        params.put("id",id);
        params.put("username",username);
        Consumer consumer=kongConsumerOperation.addConsumerAndJudege(params);
        return id;
        //Consumer consumer=kongConsumerOperation.addConsumer(params);
    }
}
